﻿/********************************************************************************/
// <copyright file="CustomMembershipProvider.cs" company="Asia E-Business Solutions">
//     Copyright © 2012. All right reserved
// </copyright>
// <history>
//     <change who="Phuoc Le" date="26/12/2012 4:21:38 PM">Created</change>
// </history>
/********************************************************************************/

using System;
using System.Security.Cryptography;
using System.Web.Security;
using JLL.China.Infrastructure;
using JLL.China.Infrastructure.Logging;
using JLL.China.Infrastructure.Services;
using System.Text;

namespace JLL.China.Application.Services.Membership
{
    public class CustomMembershipProvider : MembershipProvider
    {
        private ILogger _logger = ObjectFactory.Resolve<ILogger>();

        public override string ApplicationName { get; set; }

        public override bool ChangePassword(string username, string oldPassword, string newPassword)
        {
            var acc = AdminService.GetAdmin(username);
            if (acc != null)
            {
                if (acc.Password.Equals(oldPassword))
                {
                    acc.Password = newPassword;
                    AdminService.UpdateAdmin(acc);
                    AdminService.CommitChanges();
                    return true;
                }
                else
                {
                    _logger.Debug(string.Format("Invalid password for user {0}", oldPassword));
                }
            }
            else
            {
                _logger.Debug(string.Format("User {0} not found", username));
            }
            return false;
        }

        public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer)
        {
            throw new NotImplementedException();
        }

        public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
        {
            var args = new ValidatePasswordEventArgs(username, password, true);
            OnValidatingPassword(args);

            if (args.Cancel)
            {
                status = MembershipCreateStatus.InvalidPassword;

                return null;
            }

            if (string.IsNullOrEmpty(password))
            {
                status = MembershipCreateStatus.InvalidPassword;

                return null;
            }

            MembershipUser u = GetUser(username, false);

            if (u == null)
            {
                DateTime createDate = DateTime.Now;

                if (providerUserKey == null)
                {
                    providerUserKey = Guid.NewGuid();
                }
                else
                {
                    if (!(providerUserKey is Guid))
                    {
                        status = MembershipCreateStatus.InvalidProviderUserKey;
                        return null;
                    }
                }

                var acc = new Model.Admin();
                acc.ID = (Guid)providerUserKey;
                acc.UserName = username;
                acc.Password = CreatePasswordHash(password,acc.ID.ToString("N"));
                acc.IsSupperAdmin = false;
                try
                {
                    AdminService.CreateAdmin(acc);
                    AdminService.CommitChanges();
                    status = MembershipCreateStatus.Success;
                }
                catch (Exception ex)
                {
                    _logger.Error(ex);
                    status = MembershipCreateStatus.ProviderError;
                }
                return (MembershipUser)GetUser(username, false);
            }
            else
            {
                status = MembershipCreateStatus.DuplicateUserName;
            }
            return null;
        }

        public override bool DeleteUser(string username, bool deleteAllRelatedData)
        {
            throw new NotImplementedException();
        }

        public override bool EnablePasswordReset
        {
            get { throw new NotImplementedException(); }
        }

        public override bool EnablePasswordRetrieval
        {
            get { throw new NotImplementedException(); }
        }

        public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
        {
            throw new NotImplementedException();
        }

        public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
        {
            throw new NotImplementedException();
        }

        public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
        {
            throw new NotImplementedException();
        }

        public override int GetNumberOfUsersOnline()
        {
            throw new NotImplementedException();
        }

        public override string GetPassword(string username, string answer)
        {
            throw new NotImplementedException();
        }

        public override MembershipUser GetUser(string username, bool userIsOnline)
        {
            var acc = AdminService.GetAdmin(username);
            if (acc != null)
            {
                MembershipUser user = new MembershipUser(
                    "CustomMembershipProvider",
                    acc.UserName,
                    acc.ID,
                    null,
                    null,
                    null,
                    acc.IsActive,
                    false,
                    DateTime.MinValue,
                    DateTime.MinValue,
                    DateTime.MinValue,
                    DateTime.MinValue,
                    DateTime.MinValue);
                return user;
            }
            else
            {
                return null;
            }
        }

        public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
        {
            throw new NotImplementedException();
        }

        public override string GetUserNameByEmail(string email)
        {
            throw new NotImplementedException();
        }

        public override int MaxInvalidPasswordAttempts
        {
            get { return 5; }
        }

        public override int MinRequiredNonAlphanumericCharacters
        {
            get { throw new NotImplementedException(); }
        }

        public override int MinRequiredPasswordLength
        {
            get { return 6; }
        }

        public override int PasswordAttemptWindow
        {
            get { throw new NotImplementedException(); }
        }

        public override MembershipPasswordFormat PasswordFormat
        {
            get { throw new NotImplementedException(); }
        }

        public override string PasswordStrengthRegularExpression
        {
            get { throw new NotImplementedException(); }
        }

        public override bool RequiresQuestionAndAnswer
        {
            get { throw new NotImplementedException(); }
        }

        public override bool RequiresUniqueEmail
        {
            get { throw new NotImplementedException(); }
        }

        public override string ResetPassword(string username, string answer)
        {
            throw new NotImplementedException();
        }

        public override bool UnlockUser(string userName)
        {
            throw new NotImplementedException();
        }

        public override void UpdateUser(MembershipUser user)
        {
            throw new NotImplementedException();
        }

        public override bool ValidateUser(string username, string password)
        {
            return AdminService.ValidateLogin(username, password);
        }

        #region Private Methods

        private static string CreatePasswordHash(string password, string salt)
        {
            var snp = password + salt;

            HashAlgorithm sha256 = new SHA256Managed();

            var hashed = sha256.ComputeHash(Encoding.UTF8.GetBytes(snp));

            return Convert.ToBase64String(hashed);
        }
        #endregion
    }
}
